const fs = require('fs')
const path = require('path')
const archiver = require('archiver')
const { Readable } = require('stream')

class ZipService {
  constructor() {
    this.tempDir = path.join(__dirname, '../../temp')
    if (!fs.existsSync(this.tempDir)) {
      fs.mkdirSync(this.tempDir, { recursive: true })
    }
  }

  /**
   * 创建ZIP压缩包
   * @param {Array} files 文件列表 {path: 文件路径, name: 保存名称}
   * @param {String} zipName ZIP文件名
   * @returns {Promise<{path: String, size: Number}>}
   */
  async createZip(files, zipName) {
    return new Promise((resolve, reject) => {
      const zipPath = path.join(this.tempDir, zipName)
      const output = fs.createWriteStream(zipPath)
      const archive = archiver('zip', {
        zlib: { level: 5 } // 压缩级别
      })

      output.on('close', () => {
        resolve({
          path: zipPath,
          size: archive.pointer()
        })
      })

      archive.on('error', err => {
        reject(err)
      })

      archive.pipe(output)

      // 添加文件到压缩包
      files.forEach(file => {
        if (fs.existsSync(file.path)) {
          archive.file(file.path, { name: file.name })
        }
      })

      archive.finalize()
    })
  }

  /**
   * 流式下载ZIP包
   * @param {Array} files 文件列表 
   * @param {Object} res Express响应对象
   */
  async streamZip(files, res) {
    const archive = archiver('zip', {
      zlib: { level: 5 }
    })

    archive.on('error', err => {
      throw err
    })

    // 设置响应头
    res.attachment('downloads.zip')
    res.setHeader('Content-Type', 'application/zip')
    archive.pipe(res)

    // 添加文件
    files.forEach(file => {
      if (fs.existsSync(file.path)) {
        archive.file(file.path, { name: file.name })
      }
    })

    await archive.finalize()
  }

  /**
   * 清理临时文件
   * @param {String} zipPath 
   */
  cleanup(zipPath) {
    if (fs.existsSync(zipPath)) {
      fs.unlinkSync(zipPath)
    }
  }
}

module.exports = new ZipService()